home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / libgimp / gimpmatrix.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-26  |  8.9 KB  |  419 lines

  1. /* LIBGIMP - The GIMP Library 
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * gimpmatrix.c
  5.  * Copyright (C) 1998 Jay Cox <jaycox@earthlink.net>
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the
  19.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  * Boston, MA 02111-1307, USA.
  21.  */
  22.  
  23. #include <string.h>
  24.  
  25. #include <glib.h>
  26.  
  27. #include "gimpmath.h"
  28. #include "gimpmatrix.h"
  29.  
  30.  
  31. #define EPSILON 1e-6
  32.  
  33.  
  34. /**
  35.  * gimp_matrix3_transform_point:
  36.  * @matrix: The transformation matrix.
  37.  * @x: The source X coordinate.
  38.  * @y: The source Y coordinate.
  39.  * @newx: The transformed X coordinate.
  40.  * @newy: The transformed Y coordinate.
  41.  * 
  42.  * Transforms a point in 2D as specified by the transformation matrix.
  43.  */
  44. void
  45. gimp_matrix3_transform_point (GimpMatrix3  matrix, 
  46.                   gdouble      x, 
  47.                   gdouble      y,
  48.                   gdouble     *newx, 
  49.                   gdouble     *newy)
  50. {
  51.   gdouble w;
  52.  
  53.   w = matrix[2][0]*x + matrix[2][1]*y + matrix[2][2];
  54.  
  55.   if (w == 0.0)
  56.     w = 1.0;
  57.   else
  58.     w = 1.0/w;
  59.  
  60.   *newx = (matrix[0][0]*x + matrix[0][1]*y + matrix[0][2])*w;
  61.   *newy = (matrix[1][0]*x + matrix[1][1]*y + matrix[1][2])*w;
  62. }
  63.  
  64. /**
  65.  * gimp_matrix3_mult:
  66.  * @matrix1: The first input matrix.
  67.  * @matrix2: The second input matrix which will be oeverwritten ba the result.
  68.  * 
  69.  * Multiplies two matrices and puts the result into the second one.
  70.  */
  71. void
  72. gimp_matrix3_mult (GimpMatrix3 matrix1, 
  73.            GimpMatrix3 matrix2)
  74. {
  75.   gint i, j;
  76.   GimpMatrix3 tmp;
  77.   gdouble t1, t2, t3;
  78.  
  79.   for (i = 0; i < 3; i++)
  80.     {
  81.       t1 = matrix1[i][0];
  82.       t2 = matrix1[i][1];
  83.       t3 = matrix1[i][2];
  84.       for (j = 0; j < 3; j++)
  85.     {
  86.       tmp[i][j]  = t1 * matrix2[0][j];
  87.       tmp[i][j] += t2 * matrix2[1][j];
  88.       tmp[i][j] += t3 * matrix2[2][j];
  89.     }
  90.     }
  91.  
  92.   /*  put the results in matrix2 */
  93.   memcpy (&matrix2[0][0], &tmp[0][0], sizeof (GimpMatrix3));
  94. }
  95.  
  96. /**
  97.  * gimp_matrix3_identity:
  98.  * @matrix: A matrix.
  99.  * 
  100.  * Sets the matrix to the identity matrix.
  101.  */
  102. void
  103. gimp_matrix3_identity (GimpMatrix3 matrix)
  104. {
  105.   static GimpMatrix3 identity = { { 1.0, 0.0, 0.0 },
  106.                   { 0.0, 1.0, 0.0 },
  107.                   { 0.0, 0.0, 1.0 } };
  108.  
  109.   memcpy (&matrix[0][0], &identity[0][0], sizeof (GimpMatrix3));
  110. }
  111.  
  112. /**
  113.  * gimp_matrix3_translate:
  114.  * @matrix: The matrix that is to be translated.
  115.  * @x: Translation in X direction.
  116.  * @y: Translation in Y direction.
  117.  * 
  118.  * Translates the matrix by x and y.
  119.  */
  120. void
  121. gimp_matrix3_translate (GimpMatrix3 matrix, 
  122.             gdouble     x, 
  123.             gdouble     y)
  124. {
  125.   gdouble g, h, i;
  126.  
  127.   g = matrix[2][0];
  128.   h = matrix[2][1];
  129.   i = matrix[2][2];
  130.  
  131.   matrix[0][0] += x * g;
  132.   matrix[0][1] += x * h;
  133.   matrix[0][2] += x * i;
  134.   matrix[1][0] += y * g;
  135.   matrix[1][1] += y * h;
  136.   matrix[1][2] += y * i;
  137. }
  138.  
  139. /**
  140.  * gimp_matrix3_scale:
  141.  * @matrix: The matrix that is to be scaled.
  142.  * @x: X scale factor.
  143.  * @y: Y scale factor.
  144.  * 
  145.  * Scales the matrix by x and y 
  146.  */
  147. void
  148. gimp_matrix3_scale (GimpMatrix3 matrix, 
  149.             gdouble     x, 
  150.             gdouble     y)
  151. {
  152.   matrix[0][0] *= x;
  153.   matrix[0][1] *= x;
  154.   matrix[0][2] *= x;
  155.  
  156.   matrix[1][0] *= y;
  157.   matrix[1][1] *= y;
  158.   matrix[1][2] *= y;
  159. }
  160.  
  161. /**
  162.  * gimp_matrix3_rotate:
  163.  * @matrix: The matrix that is to be rotated.
  164.  * @theta: The angle of rotation (in radians).
  165.  * 
  166.  * Rotates the matrix by theta degrees.
  167.  */
  168. void
  169. gimp_matrix3_rotate (GimpMatrix3 matrix, 
  170.              gdouble     theta)
  171. {
  172.   gdouble t1, t2;
  173.   gdouble cost, sint;
  174.  
  175.   cost = cos (theta);
  176.   sint = sin (theta);
  177.   
  178.   t1 = matrix[0][0];
  179.   t2 = matrix[1][0];
  180.   matrix[0][0] = cost * t1 - sint * t2;
  181.   matrix[1][0] = sint * t1 + cost * t2;
  182.  
  183.   t1 = matrix[0][1];
  184.   t2 = matrix[1][1];
  185.   matrix[0][1] = cost * t1 - sint * t2;
  186.   matrix[1][1] = sint*t1 + cost*t2;
  187.  
  188.   t1 = matrix[0][2];
  189.   t2 = matrix[1][2];
  190.   matrix[0][2] = cost*t1 - sint*t2;
  191.   matrix[1][2] = sint*t1 + cost*t2;
  192. }
  193.  
  194. /**
  195.  * gimp_matrix3_xshear:
  196.  * @matrix: The matrix that is to be sheared.
  197.  * @amount: X shear amount.
  198.  * 
  199.  * Shears the matrix in the X direction.
  200.  */
  201. void
  202. gimp_matrix3_xshear (GimpMatrix3 matrix, 
  203.              gdouble     amount)
  204. {
  205.   matrix[0][0] += amount * matrix[1][0];
  206.   matrix[0][1] += amount * matrix[1][1];
  207.   matrix[0][2] += amount * matrix[1][2];
  208. }
  209.  
  210. /**
  211.  * gimp_matrix3_yshear:
  212.  * @matrix: The matrix that is to be sheared.
  213.  * @amount: Y shear amount.
  214.  * 
  215.  * Shears the matrix in the Y direction.
  216.  */
  217. void
  218. gimp_matrix3_yshear (GimpMatrix3 matrix, 
  219.              gdouble     amount)
  220. {
  221.   matrix[1][0] += amount * matrix[0][0];
  222.   matrix[1][1] += amount * matrix[0][1];
  223.   matrix[1][2] += amount * matrix[0][2];
  224. }
  225.  
  226. /**
  227.  * gimp_matrix3_determinant:
  228.  * @matrix: The input matrix. 
  229.  * 
  230.  * Calculates the determinant of the given matrix.
  231.  * 
  232.  * Returns: The determinant.
  233.  */
  234. gdouble
  235. gimp_matrix3_determinant (GimpMatrix3 matrix)
  236. {
  237.   gdouble determinant;
  238.  
  239.   determinant  = 
  240.     matrix[0][0] * (matrix[1][1]*matrix[2][2] - matrix[1][2]*matrix[2][1]);
  241.   determinant -= 
  242.     matrix[1][0] * (matrix[0][1]*matrix[2][2] - matrix[0][2]*matrix[2][1]);
  243.   determinant += 
  244.     matrix[2][0] * (matrix[0][1]*matrix[1][2] - matrix[0][2]*matrix[1][1]);
  245.  
  246.   return determinant;
  247. }
  248.  
  249. /**
  250.  * gimp_matrix3_invert:
  251.  * @matrix: The matrix that is to be inverted.
  252.  * @matrix_inv: A matrix the inverted matrix should be written into. 
  253.  * 
  254.  * Inverts the given matrix.
  255.  */
  256. void
  257. gimp_matrix3_invert (GimpMatrix3 matrix, 
  258.              GimpMatrix3 matrix_inv)
  259. {
  260.   gdouble det_1;
  261.  
  262.   det_1 = gimp_matrix3_determinant (matrix);
  263.  
  264.   if (det_1 == 0.0)
  265.     return;
  266.  
  267.   det_1 = 1.0 / det_1;
  268.  
  269.   matrix_inv[0][0] =   
  270.     (matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1]) * det_1;
  271.  
  272.   matrix_inv[1][0] = 
  273.     - (matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0]) * det_1;
  274.  
  275.   matrix_inv[2][0] =   
  276.     (matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0]) * det_1;
  277.  
  278.   matrix_inv[0][1] = 
  279.     - (matrix[0][1] * matrix[2][2] - matrix[0][2] * matrix[2][1] ) * det_1;
  280.  
  281.   matrix_inv[1][1] = 
  282.     (matrix[0][0] * matrix[2][2] - matrix[0][2] * matrix[2][0]) * det_1;
  283.  
  284.   matrix_inv[2][1] = 
  285.     - (matrix[0][0] * matrix[2][1] - matrix[0][1] * matrix[2][0]) * det_1;
  286.   
  287.   matrix_inv[0][2] =
  288.     (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1]) * det_1;
  289.   
  290.   matrix_inv[1][2] = 
  291.     - (matrix[0][0] * matrix[1][2] - matrix[0][2] * matrix[1][0]) * det_1;
  292.   
  293.   matrix_inv[2][2] = 
  294.     (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]) * det_1;
  295. }
  296.  
  297.  
  298. /**
  299.  * gimp_matrix3_duplicate:
  300.  * @src: The source matrix.
  301.  * @target: The destination matrix. 
  302.  * 
  303.  * Copies the source matrix to the destination matrix.
  304.  */
  305. void
  306. gimp_matrix3_duplicate (GimpMatrix3 src, 
  307.             GimpMatrix3 target)
  308. {
  309.   memcpy (&target[0][0], &src[0][0], sizeof (GimpMatrix3));
  310. }
  311.  
  312.  
  313. /*  functions to test for matrix properties  */
  314.  
  315.  
  316. /**
  317.  * gimp_matrix3_is_diagonal:
  318.  * @matrix: The matrix that is to be tested.
  319.  * 
  320.  * Checks if the given matrix is diagonal.
  321.  * 
  322.  * Returns: TRUE if the matrix is diagonal.
  323.  */
  324. gboolean
  325. gimp_matrix3_is_diagonal (GimpMatrix3 matrix)
  326. {
  327.   gint i, j;
  328.  
  329.   for (i = 0; i < 3; i++)
  330.     {
  331.       for (j = 0; j < 3; j++)
  332.     {
  333.       if (i != j && fabs (matrix[i][j]) > EPSILON)
  334.         return FALSE;
  335.     }
  336.     }
  337.  
  338.   return TRUE;
  339. }
  340.  
  341. /**
  342.  * gimp_matrix3_is_identity:
  343.  * @matrix: The matrix that is to be tested.
  344.  * 
  345.  * Checks if the given matrix is the identity matrix.
  346.  * 
  347.  * Returns: TRUE if the matrix is the identity matrix.
  348.  */
  349. gboolean
  350. gimp_matrix3_is_identity (GimpMatrix3 matrix)
  351. {
  352.   gint i,j;
  353.  
  354.   for (i = 0; i < 3; i++)
  355.     {
  356.       for (j = 0; j < 3; j++)
  357.     {
  358.       if (i == j)
  359.         {
  360.           if (fabs (matrix[i][j] - 1.0) > EPSILON)
  361.         return FALSE;
  362.         }
  363.       else
  364.         {
  365.           if (fabs (matrix[i][j]) > EPSILON)
  366.         return FALSE;
  367.         }
  368.     }
  369.     }
  370.  
  371.   return TRUE;
  372. }
  373.  
  374. /*  Check if we'll need to interpolate when applying this matrix. 
  375.     This function returns TRUE if all entries of the upper left 
  376.     2x2 matrix are either 0 or 1 
  377.  */
  378.  
  379.  
  380. /**
  381.  * gimp_matrix3_is_simple:
  382.  * @matrix: The matrix that is to be tested.
  383.  * 
  384.  * Checks if we'll need to interpolate when applying this matrix as
  385.  * a transformation.
  386.  * 
  387.  * Returns: TRUE if all entries of the upper left 2x2 matrix are either 
  388.  * 0 or 1
  389.  */
  390. gboolean
  391. gimp_matrix3_is_simple (GimpMatrix3 matrix)
  392. {
  393.   gdouble absm;
  394.   gint i, j;
  395.  
  396.   for (i = 0; i < 2; i++)
  397.     {
  398.       for (j = 0; j < 2; j++)
  399.     {
  400.       absm = fabs (matrix[i][j]);
  401.       if (absm > EPSILON && fabs (absm - 1.0) > EPSILON)
  402.         return FALSE;
  403.     }
  404.     }
  405.  
  406.   return TRUE;
  407. }
  408.  
  409. void
  410. gimp_matrix4_to_deg (GimpMatrix4  matrix,
  411.              gdouble     *a,
  412.              gdouble     *b,
  413.              gdouble     *c)
  414. {
  415.   *a = 180 * (asin (matrix[1][0]) / G_PI_2);
  416.   *b = 180 * (asin (matrix[2][0]) / G_PI_2);
  417.   *c = 180 * (asin (matrix[2][1]) / G_PI_2);
  418. }
  419.